﻿using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace FlashPay.Admin.Controllers
{
    using FlashPay.EF.Models;
    //自定义命名空间
    using FlashPay.Entity;
    using FlashPay.Entity.Enum;
    using FlashPay.Entity.Request.Log;
    using FlashPay.Entity.Response.User;
    using FlashPay.Service.Interface;
    using FlashPay.Util;
    using Microsoft.AspNetCore.Http;

    #region 基础控制
    /// <summary>
    /// 基础控制
    /// </summary>
    public class BaseController : Controller
    {
        /// <summary>
        /// 票据
        /// </summary>
        public readonly IAuthenticate<TicketResponse> _manage;

        /// <summary>
        /// 
        /// </summary>
        public readonly IHttpContextAccessor _accessor;

        /// <summary>
        /// 
        /// </summary>
        public static TicketResponse ticketResponse;

        /// <summary>
        /// 注入
        /// </summary>
        public BaseController(IAuthenticate<TicketResponse> manage, IHttpContextAccessor accessor)
        {
            _manage = manage;
            _accessor = accessor;
        }

        /// <summary>
        /// OnActionExecuting
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {

            var token = string.IsNullOrEmpty(filterContext.HttpContext.Request.Query["token"].ToString()) ? filterContext.HttpContext.Request.Headers["token"]:filterContext.HttpContext.Request.Query["token"];

            if (!string.IsNullOrEmpty(token))
            {
                _manage.GetTicket(token);

                ticketResponse = _manage.Get(token);

                if (_manage.data == null)
                {
                    filterContext.Result = new JsonResult(new
                    {
                        Success = false,
                        ErrorMessage = "授权失败！",
                        ErrorCode = "200",
                        Callback = @"FlashPay.UI.LoginBox()"
                    });
                }
            }
            else {
                filterContext.Result = new JsonResult(new
                {
                    Success = false,
                    ErrorMessage = "授权失败！请联系管理员！",
                    ErrorCode = "200",
                    Callback = @"FlashPay.UI.LoginBox()"
                });
            }
        }

        /// <summary>
        /// 获取当前用户信息
        /// </summary>
        /// <returns></returns>
        public JResult<TicketResponse> GetTicketResponse()
        {
            var response = new JResult<TicketResponse>() {
                Success = false
            };

            try
            {
                var token = string.IsNullOrEmpty(HttpContext.Request.Query["token"].ToString()) ? HttpContext.Request.Headers["token"] : HttpContext.Request.Query["token"];

                if (!string.IsNullOrEmpty(token))
                {
                    response.Data = _manage.Get(token);
                    response.Success = true;
                }
            }
            catch (Exception ex) {
                response.ErrorCode = "000";
                response.ErrorMessage = ex.Message;
            }

            return response;
        }

        /// <summary>
        /// 销毁对象
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            ticketResponse = null;

            base.OnActionExecuted(context);
        }
    }
    #endregion

    #region 自定义方法拦截器
    /// <summary>
    /// 自定义方法拦截器
    /// </summary>
    /// <remarks>2018-06-01 创建</remarks>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
    public class AuthorizeFilter : ActionFilterAttribute
    {
        /// <summary>
        /// 授权码列表
        /// </summary>
        public AuthCode[] Code { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="code">权限码</param>
        public AuthorizeFilter(params AuthCode[] code)
        {
            this.Code = code;
        }

        /// <summary>
        /// 拦截未登录的用户
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var IsAjaxRequest = false;

            var headers = context.HttpContext.Request.Headers.ContainsKey("x-requested-with");
            if (headers)
            {
                IsAjaxRequest = context.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest";
            }

            var token = string.IsNullOrEmpty(context.HttpContext.Request.Query["token"].ToString()) ? context.HttpContext.Request.Headers["token"] : context.HttpContext.Request.Query["token"];

            if (string.IsNullOrEmpty(token))
            {
                context.Result = new JsonResult(new
                {
                    Success = false,
                    ErrorCode = "200！",
                    ErrorMessage = "登录失败,token验证失败！",
                    Callback = @"FlashPay.UI.LoginBox()",
                });
            }
            else
            {
                try
                {

                    var ticketResponse = new MemoryCacheUtil().Get<TicketResponse>(EncryptHelper.deCryptDES(token));
                    if (ticketResponse == null)
                    {
                        context.Result = new JsonResult(new
                        {
                            Success = false,
                            ErrorCode = "200",
                            ErrorMessage = "登录失败，未找到Token对象！",
                            Callback = @"FlashPay.UI.LoginBox()"
                        });
                    }
                    else
                    {
                        var isAuthority = Code.Any(item => ticketResponse.UserPermission.Contains(item.ToString()));
                        if (!isAuthority)
                        {
                            int isEdit = 0;
                            if (Code.Contains(AuthCode.AllowEdit)){
                                isEdit = 1;
                            }

                            var result = new JsonResult(new
                            {
                                Success = false,
                                ErrorCode = "100",
                                Callback = string.Format("FlashPay.UI.NoPrivilege({0})", isEdit)
                            });
                            context.Result = result;
                        }
                    }
                }
                catch(Exception ex)
                {
                    context.Result = new JsonResult(new
                    {
                        Success = false,
                        ErrorCode = "200",
                        ErrorMessage = ex.Message,
                        Callback = @"FlashPay.UI.LoginBox()",
                    });
                }
            }
        }
    }
    #endregion

    #region 自定义全局异常过滤器
    // <summary>
    /// 自定义全局异常过滤器
    /// </summary>
    public class HttpGlobalExceptionFilter : ExceptionFilterAttribute
    {
        private readonly LogService _logService;

        /// <summary>
        /// 日志模型
        /// </summary>
        private readonly LogRecord _logRecord;

        /// <summary>
        /// 注入
        /// </summary>
        public HttpGlobalExceptionFilter(LogService logService,LogRecord logRecord)
        {
            this._logService = logService;
            this._logRecord = logRecord;
        }

        public override void OnException(ExceptionContext context)
        {
            var response = new JResult()
            {
                Success = false
            };

            //执行过程出现未处理异常
            Exception ex = context.Exception;

            response.ErrorCode = "500";
            response.ErrorMessage = ex.Message;

            context.Result = new JsonResult(response);
            context.HttpContext.Response.StatusCode = 200;
            context.ExceptionHandled = true;

            try
            {
                var log = new LogRecordRequest() {
                    Ip = _logRecord.Ip,
                    LogType = LogRecordLogType.Log_Add,
                    CreateName = _logRecord.CreateName,
                    CreateUid = _logRecord.CreateUid,
                    LogRemark = "系统全局日志："+ex.Message,
                    CompanyId = _logRecord.CompanyId,
                    RequestUrl = _logRecord.RequestUrl,
                    RequestData = ex.StackTrace
                };
                _logService.AddLog(log);
            }
            catch {

            }

            base.OnException(context);
        }
    }
    #endregion
    
}

namespace FlashPay.Admin
{
    using FlashPay.Entity;
    using FlashPay.Entity.Response.User;
    //自定义命名空间
    using FlashPay.Util;

    /// <summary>
    /// 认证接口
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IAuthenticate<T>
    {
        T data { set; get; }

        /// <summary>
        /// 获取票据
        /// </summary>
        /// <param name="token"></param>
        void GetTicket(string token);

        /// <summary>
        /// 获取票据
        /// </summary>
        /// <param name="token"></param>
        TicketResponse Get(string token);

        /// <summary>
        /// 设置票据
        /// </summary>
        /// <param name="token"></param>
        JResult<string> SetTicket();


        /// <summary>
        /// 删除票据
        /// </summary>
        /// <param name="key"></param>
        void RemoveTicket(string key);
    }

    public class AuthenticateImpl<T> : IAuthenticate<T>
    {

        #region 注入
        /// <summary>
        /// 缓存
        /// </summary>
        private MemoryCacheUtil _cache;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cache">缓存</param>
        public AuthenticateImpl(MemoryCacheUtil cache)
        {
            this._cache = cache;
        }
        #endregion

        public T data { set; get; }

        /// <summary>
        /// 获取票据
        /// </summary>
        /// <param name="token"></param>
        public void GetTicket(string token)
        {
            this.data = _cache.Get<T>(EncryptHelper.deCryptDES(token));
        }

        /// <summary>
        /// 获取票据
        /// </summary>
        /// <param name="token"></param>
        public TicketResponse Get(string token)
        {
            return _cache.Get<TicketResponse>(EncryptHelper.deCryptDES(token));
        }

        /// <summary>
        /// 设置票据
        /// </summary>
        /// <param name="token"></param>
        public JResult<string> SetTicket()
        {
            var response = new JResult<string>()
            {
                Success = false
            };

            try
            {
                //生成Token
                var token = Guid.NewGuid().ToString("N");
                //设置缓存
                var status = _cache.Set(token, data, 300);
                if (status)
                {
                    //验证是否存在
                    var existsStatus = _cache.Exists(token);
                    if (existsStatus)
                    {
                        response.Success = true;
                        response.Data = EncryptHelper.enCryptDES(token);
                    }
                }

            }
            catch (Exception ex)
            {
                response.ErrorMessage = ex.Message;
            }

            return response;
        }

        /// <summary>
        /// 删除票据
        /// </summary>
        /// <param name="key"></param>
        public void RemoveTicket(string token) {
            try
            {
                _cache.Remove(EncryptHelper.deCryptDES(token));
            }
            catch (Exception ex) { }
        }
    }
}